const MAX_NUMBER: i32 = 1000; // 定义常量
fn main() {
    // 变量声明使用let
    // 默认情况变量不可变
    // 声明变量在变量前加上mut变量就可以改变
    let mut x = 5;
    println!("this value if x is {}", x);
    x = 6;
    println!("this value if x is {}", x);
    // 常量：绑定值以后也是不可变的，但是它与不可变的变量有很多区别：
    // 不可使用mut，常量永远都是不可变的
    // 声明常量使用const关键字，他的类型必须被标注
    // 常量可以在任何作用域内进行声明，包括全局作用域
    // 只能绑定常量表达式不能绑定到函数的调用结果或只能在运行时才能计算出的值
    // 运行期间在作用域内一直有效
    // 命名规范rust使用全大写字母，每个单词之间用下划线分割

    // 隐藏（shadowing）
    // 可以使用相同的名字定义新的变量，新的变量就会shadowing隐藏之前的同名变量
    // 如果不使用let关键字，name重新给非mut的变量赋值会导致编译报错
    // 而使用let声明的同名新变量也是不可变的
    // 使用let生命的同名新变量，他的类型可以和之前不同
    // 不報錯
    // let space = "    ";
    // let space = space.len();
    // 報錯
    // let space = "    ";
    // space = space.len();

    // 报错
    // let mut space = "    ";
    // space = space.len();

    // 数据类型（标量和复合类型）
    // rust是静态编译语言，在编译时必须知道所有变量的类型
    // 基于使用的值，编译器通常能够推断出他的具体类型
    // 但是如果可能的类型比较多比如把string转为整数类型额parse方法。就必须添加类型标注否则编译报错
    // 标量
    // 复合类型（元组）
    // 元组
    let tup: (i32, f64, u8) = (500, 6.4, 1); // 元祖可以看成类数组对象
    println!("{},{},{}", tup.0, tup.1, tup.2);
    // 数组
    // 类型必须相同
    // 长度是固定的
    // 如果你想让你的数据存放在stack栈上而不是heap堆上，或者想保证有固定数量的元素，这时数组更好
    // vectar比数组灵活可以改变长度
    // rust是stack上分配的单个块的内存
    // 可以使用索引来访问数组的元素
    // 如果访问的索引超出数组的范围那么编译不会报错（简单情况下）但是运行会报错，rust不会让其继续访问相同的内存地址
    let arr = [1, 2, 3, 4, 5];
    let arr1 = [3; 5]; // 长度5每个值都是3
    println!("{}", arr[1]);
    test_function(100);
    test();
    loop_fn();
    while_fn();
    for_fn();
}

// 函数
// 声明函数使用fn
// 命名规范：所有字母都是小写使用下划线连接
// 必须声明参数类型
// 不能用let定义变量等于函数
// let a = (let x = 10);
// ->定义函数返回类型
fn test_function(value: i32) -> i32 {
    println!("{}", value);
    return value;
    // value
    // value; // 有分号这是错的类似于return();
}

fn test() {
    // if else 要自己轉化成true或者false
    let number = 3;
    let number1 = if number > 2 { 5 } else { 10 };
    if number > 5 {
        println!("1,{}", number1);
    } else {
        println!("2,{}", number1);
    }
}

// 循环
fn loop_fn() {
    let mut num = 0;
    let res = loop {
        num += 1;
        print!("num:{}", num);
        if num == 10 {
            break num * 2;
        }
    };
    print!("res:{}", res);
}

// 循环
fn while_fn() {
    let mut while_num = 0;
    while while_num < 10 {
        println!("while_num:{}", while_num);
        while_num += 1;
    };
}

// 循环最好使用for循环，使用while和loop低效且易错

// for循环
fn for_fn() {
    let a = [1, 2, 3, 4, 5];
    for item in a.iter() {
        println!("{}", item);
    }
    for item in a {
        println!("{}", item);
    }
    // 1-4不包括5，rev反轉
    for number in (1..5).rev() {
        println!("number:{}", number);
    }
}